package controlFlowGraph;

import java.util.HashSet;
import java.util.Set;

import domains.Interval;
import domains.IntervalBound;
import domains.IntervalDomain;

import parser.Token;

public class UnaryOp extends Expression {

	private Expression operand;
	
	private Token operator;
	
	public UnaryOp(Expression operand, Token operator) {
		this.operand = operand;
		this.operator = operator;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof UnaryOp) {
			UnaryOp un = (UnaryOp) obj;
			return (this.getOperator().equals(un.getOperator())) &&
				(this.getOperand().equals(un.getOperand()));
		}
		return false;
	}

	@Override
	public int hashCode() {
		return operand.hashCode();
	}

	@Override
	public String toString() {
		return operator.getText() + operand.toString();
	}

	public Expression getOperand() {
		return operand;
	}

	public Token getOperator() {
		return operator;
	}
	
	@Override
	public Set<Variable> getInvolvedVariables() {
		Set<Variable> res = new HashSet<Variable>();
		res.addAll(this.operand.getInvolvedVariables());
		return res;
	}
	
	@Override
	public Interval abstractExpressionEvaluation(IntervalDomain dom){
		Interval exp;
		switch(this.operator.getType()){
			case MINUS:
				exp = (this.operand.abstractExpressionEvaluation(dom)).negate();
				break;
			default:
				System.out.println("Unknown unary operator!");
				IntervalBound left = new IntervalBound(null,true,false);
				IntervalBound right = new IntervalBound(null,false,true);
				exp = new Interval(left,right);
		}
		return exp;
	}
	
	@Override
	public void replaceVariable(Variable v, Constant c){
		if(this.operand instanceof Variable){
			if(((Variable) this.operand).equals(v)){
				this.operand = c;
			}
		} else {
			this.operand.replaceVariable(v, c);
		}
	}
}
